﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IterationLife.Mobile.AppServices.Dtos.System;
using IterationLife.System.Repositories;

namespace IterationLife.Mobile.AppServices.Services.System.Implements
{
    public class GeolocationService : IGeolocationService
    {
        private readonly IDistrictRepository _districtRepository;

        private static List<ProvinceOutput> _geolocationCache;

        public GeolocationService(IDistrictRepository districtRepository)
        {
            _districtRepository = districtRepository;
        }

        public List<ProvinceOutput> GetAllGeolocations()
        {
            if (_geolocationCache == null)
            {
                _geolocationCache= GetAllGeolocationFromDB();
            }

            return _geolocationCache;
        }

        private List<ProvinceOutput> GetAllGeolocationFromDB()
        {
            var geolocations = _districtRepository.Find()
                .Select(d => new GeolocationOutput
                {
                    Name = d.Name,
                    MergerName = d.MergerName,
                    Code = d.Code,
                    CodePath = d.CodePath,
                    Level = d.Level
                }).ToList();

            var provinces = geolocations.Where(d => d.Level == 1)
                .Select(d => new ProvinceOutput
                {
                    Name = d.Name,
                    MergerName = d.MergerName,
                    Code = d.Code,
                    CodePath = d.CodePath,
                    Level = d.Level
                }).ToList();

            provinces.ForEach(province =>
            {
                province.Cities = geolocations.Where(d => d.Level == 2 && d.CodePath.StartsWith(province.CodePath))
                    .Select(d => new CityOutput
                    {
                        Name = d.Name,
                        MergerName = d.MergerName,
                        Code = d.Code,
                        CodePath = d.CodePath,
                        Level = d.Level
                    }).ToList();

                province.Cities.ForEach(city =>
                {
                    city.Areas = geolocations.Where(d => d.Level == 3 && d.CodePath.StartsWith(city.CodePath))
                        .Select(d => new AreaOutput()
                        {
                            Name = d.Name,
                            MergerName = d.MergerName,
                            Code = d.Code,
                            CodePath = d.CodePath,
                            Level = d.Level
                        }).ToList();
                });
            });
            return provinces;
        }

        public List<GeolocationOutput> GetGeolocations(string parentCode = null)
        {
            var geolocations = _districtRepository.Find().Where(d=>d.ParentCode==parentCode)
                .Select(d=>new GeolocationOutput
                {
                    Name = d.Name,
                    MergerName = d.MergerName,
                    Code = d.Code,
                    CodePath = d.CodePath,
                    Level = d.Level
                }).ToList();

            return geolocations;
        }
    }
}
